<%@page contentType="text/html;charset=UTF-8"%>

<%@ page import="org.jfree.*"%>
<%@ page import="org.jfree.chart.*"%>
<%@ page import="org.jfree.chart.ChartPanel"%>
<%@ page import="org.jfree.chart.JFreeChart"%>
<%@ page import="org.jfree.chart.axis.NumberAxis"%>
<%@ page import="org.jfree.chart.plot.CategoryPlot"%>
<%@ page import="org.jfree.chart.plot.PlotOrientation"%>
<%@ page import="org.jfree.data.category.CategoryDataset"%>
<%@ page import="org.jfree.data.category.DefaultCategoryDataset"%>
<%@ page import="org.jfree.chart.servlet.ServletUtilities"%>
<%@ page import="org.jfree.chart.renderer.category.LineAndShapeRenderer"%>
<%@ page import="java.awt.Color"%>
<%@ page import="java.awt.BasicStroke"%>
<%@ page import="org.jfree.chart.renderer.category.CategoryItemRenderer"%>
<%@ page import="org.jfree.chart.axis.CategoryAxis"%>
<%@ page import="java.text.DecimalFormat" %>
<%@ include file='DatabaseSetup.jsp'%>

<%
    String difficult = request.getParameter("pid");
    String userID = (String) session.getAttribute("user");

    String sql="";
    ResultSet rs=null;

    int max =0;
    int min =0;

    if(Integer.parseInt(difficult)!=0){
        if(Integer.parseInt(difficult)==1){min=30; max=81;}
        if(Integer.parseInt(difficult)==2){min=25; max=29;}
        if(Integer.parseInt(difficult)==3){min=0; max=24;}

        sql="select Count(*) from gamepuzzles where numgivencells between " + min + " and " + max +
            " and puzzleID in (select puzzleID from gameSkillsMatrix where userID = " +userID +") order by puzzleID";
        rs = stmt.executeQuery(sql);
        rs.next();
        int rowCount = Integer.parseInt(rs.getString(1));
        int[] puzzleIDs = new int[rowCount];

        sql="select puzzleID from gamepuzzles where numgivencells between " + min + " and " + max +
            " and puzzleID in (select puzzleID from gameSkillsMatrix where userID = " +userID +") order by puzzleID";
        rs = stmt.executeQuery(sql);
        int i=0;
        while(rs.next()){
            puzzleIDs[i]= Integer.parseInt(rs.getString(1));
            i++;
        }
    %>

<%
    /* Prepare the data needed */

    DecimalFormat twoDForm = new DecimalFormat("#.##");

    /* Count the number of opportunity to practice the rule */
    double []SingleInGroup = new double[puzzleIDs.length];
    double []NakedSingle = new double[puzzleIDs.length];
    double []HiddenSingle = new double[puzzleIDs.length];
    double []IntersectionReduction = new double[puzzleIDs.length];
    double []NakedPairs = new double[puzzleIDs.length];
    double []HiddenPairs = new double[puzzleIDs.length];
    double []TotalRules = new double[puzzleIDs.length];

    for(i=0; i<puzzleIDs.length; i++){
        sql = "select Count(*) from gameskillsmatrix where userID = "
            + userID + " and puzzleID = " + puzzleIDs[i] + " and SingleInGroup='1'";
        rs = stmt.executeQuery(sql);
        rs.next();
        SingleInGroup[i] = Double.parseDouble(rs.getString(1));

        sql = "select Count(*) from gameskillsmatrix where userID = "
            + userID + " and puzzleID = " + puzzleIDs[i] + " and NakedSingle='1'";
        rs = stmt.executeQuery(sql);
        rs.next();
        NakedSingle[i] = Double.parseDouble(rs.getString(1));

        sql = "select Count(*) from gameskillsmatrix where userID = "
            + userID + " and puzzleID = " + puzzleIDs[i] + " and HiddenSingle='1'";
        rs = stmt.executeQuery(sql);
        rs.next();
        HiddenSingle[i] = Double.parseDouble(rs.getString(1));

        sql = "select Count(*) from gameskillsmatrix where userID = "
            + userID + " and puzzleID = " + puzzleIDs[i] + " and IntersectionReduction='1'";
        rs = stmt.executeQuery(sql);
        rs.next();
        IntersectionReduction[i] = Double.parseDouble(rs.getString(1));

        sql = "select Count(*) from gameskillsmatrix where userID = "
            + userID + " and puzzleID = " + puzzleIDs[i] + " and NakedPairs='1'";
        rs = stmt.executeQuery(sql);
        rs.next();
        NakedPairs[i] = Double.parseDouble(rs.getString(1));

        sql = "select Count(*) from gameskillsmatrix where userID = "
            + userID + " and puzzleID = " + puzzleIDs[i] + " and HiddenPairs='1'";
        rs = stmt.executeQuery(sql);
        rs.next();
        HiddenPairs[i] = Double.parseDouble(rs.getString(1));

        TotalRules[i] = SingleInGroup[i] + NakedSingle[i] + HiddenSingle[i] +
                IntersectionReduction[i] + NakedPairs[i] + HiddenPairs[i];
    }

    /* Count the number of rules applied successfully */
    double []SingleInGroupApplied = new double[puzzleIDs.length];
    double []NakedSingleApplied =new double[puzzleIDs.length];
    double []HiddenSingleApplied = new double[puzzleIDs.length];
    double []IntersectionReductionApplied = new double[puzzleIDs.length];
    double []NakedPairsApplied = new double[puzzleIDs.length];
    double []HiddenPairsApplied = new double[puzzleIDs.length];
    double []TotalRulesApplied = new double[puzzleIDs.length];

    for(i=0; i<puzzleIDs.length; i++){
        sql = "select Count(*) from gamesolvingsteps where userID = "
            + userID + " and puzzleID = " + puzzleIDs[i] + " and SingleInGroup='1' and AnswerHint='0'";
        rs = stmt.executeQuery(sql);
        rs.next();
        SingleInGroupApplied[i] = Double.parseDouble(rs.getString(1));

        sql = "select Count(*) from gamesolvingsteps where userID = "
            + userID + " and puzzleID = " + puzzleIDs[i] + " and NakedSingle='1' and AnswerHint='0'";
        rs = stmt.executeQuery(sql);
        rs.next();
        NakedSingleApplied[i] = Double.parseDouble(rs.getString(1));

        sql = "select Count(*) from gamesolvingsteps where userID = "
            + userID + " and puzzleID = " + puzzleIDs[i] + " and HiddenSingle='1' and AnswerHint='0'";
        rs = stmt.executeQuery(sql);
        rs.next();
        HiddenSingleApplied[i] = Double.parseDouble(rs.getString(1));

        sql = "select Count(distinct gridID) from gameelmincellentries where userID = "
            + userID + " and puzzleID = " + puzzleIDs[i] + " and IntersectReduct='1' and GivenByHintsFlg='0'";
        rs = stmt.executeQuery(sql);
        rs.next();
        IntersectionReductionApplied[i] = Double.parseDouble(rs.getString(1));

        sql = "select Count(distinct gridID) from gameelmincellentries where userID = "
            + userID + " and puzzleID = " + puzzleIDs[i] + " and NakedPairs='1' and GivenByHintsFlg='0'";
        rs = stmt.executeQuery(sql);
        rs.next();
        NakedPairsApplied[i] = Double.parseDouble(rs.getString(1));

        sql = "select Count(distinct gridID) from gameelmincellentries where userID = "
            + userID + " and puzzleID = " + puzzleIDs[i] + " and HiddenPairs='1' and GivenByHintsFlg='0'";
        rs = stmt.executeQuery(sql);
        rs.next();
        HiddenPairsApplied[i] = Double.parseDouble(rs.getString(1));

        TotalRulesApplied[i] = SingleInGroupApplied[i] + NakedSingleApplied[i] + HiddenSingleApplied[i] +
                IntersectionReductionApplied[i] + NakedPairsApplied[i] + HiddenPairsApplied[i];
    }

    /* Find the total number of hints Used */
    int []rowHints = new int[puzzleIDs.length];
    int []colHints = new int[puzzleIDs.length];
    int []rulesHints = new int[puzzleIDs.length];
    int []answerHints = new int[puzzleIDs.length];
    int []totalHints = new int[puzzleIDs.length];
    String []HintsUsedPrecent = new String[puzzleIDs.length];

    for(i=0; i<puzzleIDs.length; i++){
        sql = "select Count(*) from gamesolvingsteps where userID = "
            + userID + " and puzzleID = " + puzzleIDs[i] + " and rowHint = '1'";
        rs = stmt.executeQuery(sql);
        rs.next();
        rowHints[i] = Integer.parseInt(rs.getString(1));

        sql = "select Count(*) from gamesolvingsteps where userID = "
            + userID + " and puzzleID = " + puzzleIDs[i] + " and colHint = '1'";
        rs = stmt.executeQuery(sql);
        rs.next();
        colHints[i] = Integer.parseInt(rs.getString(1));

        sql = "select Count(*) from gamesolvingsteps where userID = "
            + userID + " and puzzleID = " + puzzleIDs[i] + " and rulesHint = '1'";
        rs = stmt.executeQuery(sql);
        rs.next();
        rulesHints[i] = Integer.parseInt(rs.getString(1));

        sql = "select Count(*) from gamesolvingsteps where userID = "
            + userID + " and puzzleID = " + puzzleIDs[i] + " and answerHint = '1'";
        rs = stmt.executeQuery(sql);
        rs.next();
        answerHints[i] = Integer.parseInt(rs.getString(1));

        totalHints[i] = rowHints[i] + colHints[i] + rulesHints[i] + answerHints[i];
    }

    /* find the total number of cells needed to be solved */
    double []numCellSolved = new double[puzzleIDs.length];
    for(i=0; i<puzzleIDs.length; i++){
        sql = "select NumGivenCells from gamepuzzles where puzzleID = "
               + puzzleIDs[i] ;
        rs = stmt.executeQuery(sql);
        rs.next();
        numCellSolved[i] = Double.parseDouble(rs.getString(1));
    }

    for(i=0; i<puzzleIDs.length; i++){
        if(numCellSolved[i]!=0){
            HintsUsedPrecent[i] = twoDForm.format((totalHints[i]/(numCellSolved[i]*4))*100);
        }else{
            HintsUsedPrecent[i] = "N/A";
        }
    }



    /* get the total time to solve the puzzle */
    int []elapsedTime = new int[puzzleIDs.length];

    for(i=0; i<puzzleIDs.length; i++){
        sql = "select ElapsedTime from gamesolvingsteps where userID = "
            + userID + " and puzzleID = " + puzzleIDs[i] + " order by StepID desc";
        rs = stmt.executeQuery(sql);
        rs.next();
        elapsedTime[i] = Integer.parseInt(rs.getString(1));
    }

    String []SingleInGroupPrecent = new String[puzzleIDs.length];
    String []NakedSinglePrecent = new String[puzzleIDs.length];
    String []HiddenSinglePrecent = new String[puzzleIDs.length];
    String []IntersectionReductionPrecent = new String[puzzleIDs.length];
    String []NakedPairsPrecent = new String[puzzleIDs.length];
    String []HiddenPairsPrecent = new String[puzzleIDs.length];
    String []TotalRulesPrecent = new String[puzzleIDs.length];

    for(i=0; i<puzzleIDs.length; i++){
        if(SingleInGroup[i]!=0){
            SingleInGroupPrecent[i] = twoDForm.format(SingleInGroupApplied[i]/SingleInGroup[i]*100);
        }else{
            SingleInGroupPrecent[i] = "N/A";
        }
         if(NakedSingle[i]!=0){
            NakedSinglePrecent[i] = twoDForm.format(NakedSingleApplied[i]/NakedSingle[i]*100);
        }else{
            NakedSinglePrecent[i] = "N/A";
        }
        if(HiddenSingle[i]!=0){
            HiddenSinglePrecent[i] = twoDForm.format(HiddenSingleApplied[i]/HiddenSingle[i]*100);
        }else{
            HiddenSinglePrecent[i] = "N/A";
        }
        if(IntersectionReduction[i]!=0){
            IntersectionReductionPrecent[i] = twoDForm.format(IntersectionReductionApplied[i]/IntersectionReduction[i]*100);
        }else{
            IntersectionReductionPrecent[i] = "N/A";
        }
        if(NakedPairs[i]!=0){
            NakedPairsPrecent[i] = twoDForm.format(NakedPairsApplied[i]/NakedPairs[i]*100);
        }else{
            NakedPairsPrecent[i] = "N/A";
        }
        if(HiddenPairs[i]!=0){
            HiddenPairsPrecent[i] = twoDForm.format(HiddenPairsApplied[i]/HiddenPairs[i]*100);
        }else{
            HiddenPairsPrecent[i] = "N/A";
        }
        if(TotalRules[i] !=0){
            TotalRulesPrecent[i] = twoDForm.format(TotalRulesApplied[i]/TotalRules[i]*100);
        }else{
            TotalRulesPrecent[i] = "N/A";
        }
    }
    /* find the misconception that made by user*/
    double []misconception = new double[puzzleIDs.length];
    String []misconceptionPrecent = new String[puzzleIDs.length];
    for(i=0; i<puzzleIDs.length; i++){
        sql = "select misconception from usermisconception where userID = "
                + userID + " and puzzleID = " + puzzleIDs[i] ;
        rs = stmt.executeQuery(sql);
        rs.next();
        misconception[i] = Double.parseDouble(rs.getString(1));

        if (TotalRulesApplied[i] !=0 ){
            misconceptionPrecent[i] = twoDForm.format(misconception[i]/TotalRules[i]*100);
        }
        else{
            misconceptionPrecent[i] = "N/A";
        }
    }

%>

<%
    /* Create Performance chart */

    /* Prepare row info */
    final String SGseries = "Single In Group";
    final String NSseries = "Naked Single";
    final String HSseries = "Hidden Single";
    final String IRseries = "Intersection Reduction";
    final String NPseries = "Naked Pairs";
    final String HPseries = "Hidden Pairs";

    /* Prepare column Info */
    String[] puzzleIDstr = new String[puzzleIDs.length];
    for(i=0; i<puzzleIDs.length; i++){
        puzzleIDstr[i] = Integer.toString(puzzleIDs[i]);
    }

    final DefaultCategoryDataset dataset = new DefaultCategoryDataset();

    for(i=0; i<puzzleIDs.length; i++){
        if(SingleInGroupPrecent[i]!="N/A"){
            dataset.addValue(Double.parseDouble(SingleInGroupPrecent[i]), SGseries, puzzleIDstr[i]);
        }else{
            dataset.addValue(0.0, SGseries, puzzleIDstr[i]);
        }
        if(NakedSinglePrecent[i]!="N/A"){
            dataset.addValue(Double.parseDouble(NakedSinglePrecent[i]), NSseries, puzzleIDstr[i]);
        }else{
            dataset.addValue(0.0, NSseries, puzzleIDstr[i]);
        }
        if(HiddenSinglePrecent[i]!="N/A"){
            dataset.addValue(Double.parseDouble(HiddenSinglePrecent[i]), HSseries, puzzleIDstr[i]);
        }else{
            dataset.addValue(0.0, HSseries, puzzleIDstr[i]);
        }
        if(IntersectionReductionPrecent[i]!="N/A"){
            dataset.addValue(Double.parseDouble(IntersectionReductionPrecent[i]), IRseries, puzzleIDstr[i]);
        }else{
            dataset.addValue(0.0, IRseries, puzzleIDstr[i]);
        }
        if(NakedPairsPrecent[i]!="N/A"){
            dataset.addValue(Double.parseDouble(NakedPairsPrecent[i]), NPseries, puzzleIDstr[i]);
        }else{
            dataset.addValue(0.0, NPseries, puzzleIDstr[i]);
        }
        if(HiddenPairsPrecent[i]!="N/A"){
            dataset.addValue(Double.parseDouble(HiddenPairsPrecent[i]), HPseries, puzzleIDstr[i]);
        }else{
            dataset.addValue(0.0, HPseries, puzzleIDstr[i]);
        }
    }

    JFreeChart rulesChart = ChartFactory.createLineChart(
        "Performance Chart",       // chart title
        "Puzzle ID",                   // domain axis label
        "Precentage that rules successfully applied",                   // range axis label
        dataset,                   // data
        PlotOrientation.VERTICAL,  // orientation
        true,                      // include legend
        true,                      // tooltips
        false                      // urls
    );
        rulesChart.setBackgroundPaint(Color.white);

    CategoryPlot plot = rulesChart.getCategoryPlot();
    plot.setBackgroundPaint(Color.white);
    plot.setDomainGridlinePaint(Color.white);
    plot.setRangeGridlinePaint(Color.white);

    final LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer();

    renderer.setShapesVisible(true);
    
    renderer.setSeriesPaint(0, Color.red);
    renderer.setSeriesPaint(1, Color.blue);
    renderer.setSeriesPaint(2, Color.green);
    renderer.setSeriesPaint(3, Color.MAGENTA);
    renderer.setSeriesPaint(4, Color.orange);
    renderer.setSeriesPaint(5,  Color.cyan);


    renderer.setStroke(

    new BasicStroke(2f, BasicStroke.JOIN_ROUND, BasicStroke.JOIN_BEVEL)

    );

    String rulesChartfilename = ServletUtilities.saveChartAsPNG(rulesChart,  550, 450, null, session);
    String rulesChartURL = request.getContextPath() + "/DisplayChart?filename=" + rulesChartfilename;
    out.println();

%>

<%
    /* Create Hints Usage chart */

    /* Prepare row info */
    final String RHseries = "Row Hints";
    final String CHseries = "Column Hints";
    final String LHseries = "Logical Rules Hints";
    final String AHseries = "Direct Answer Hints";
    final String THseries = "Total Number of Hints";

    /* Prepare column Info */

    final DefaultCategoryDataset hintsdataset = new DefaultCategoryDataset();

    for(i=0; i<puzzleIDs.length; i++){

        hintsdataset.addValue(rowHints[i], RHseries, puzzleIDstr[i]);
        hintsdataset.addValue(colHints[i], CHseries, puzzleIDstr[i]);
        hintsdataset.addValue(rulesHints[i], LHseries, puzzleIDstr[i]);
        hintsdataset.addValue(answerHints[i], AHseries, puzzleIDstr[i]);
        hintsdataset.addValue(totalHints[i], THseries, puzzleIDstr[i]);

    }

    JFreeChart hintsChart = ChartFactory.createLineChart(
        "Hints Usage Chart",       // chart title
        "Puzzle ID",                   // domain axis label
        "Number of Hints used",                   // range axis label
        hintsdataset,                   // data
        PlotOrientation.VERTICAL,  // orientation
        true,                      // include legend
        true,                      // tooltips
        false                      // urls
    );
        hintsChart.setBackgroundPaint(Color.white);

    CategoryPlot hintsplot = hintsChart.getCategoryPlot();
    hintsplot.setBackgroundPaint(Color.white);
    hintsplot.setDomainGridlinePaint(Color.white);
    hintsplot.setRangeGridlinePaint(Color.white);

    final LineAndShapeRenderer hintsrenderer = (LineAndShapeRenderer) hintsplot.getRenderer();

    hintsrenderer.setShapesVisible(true);

    hintsrenderer.setSeriesPaint(0, Color.red);
    hintsrenderer.setSeriesPaint(1, Color.blue);
    hintsrenderer.setSeriesPaint(2, Color.green);
    hintsrenderer.setSeriesPaint(3, Color.MAGENTA);
    hintsrenderer.setSeriesPaint(4, Color.orange);


    hintsrenderer.setStroke(

    new BasicStroke(2f, BasicStroke.JOIN_ROUND, BasicStroke.JOIN_BEVEL)

    );

    String hintsChartfilename = ServletUtilities.saveChartAsPNG(hintsChart,  550, 450, null, session);
    String hintsChartURL = request.getContextPath() + "/DisplayChart?filename=" + hintsChartfilename;
    out.println();

%>

<%
    /* Create Misconception, rules precentage relation chart */

    /* Prepare row info */
    final String MCseries = "Misconception";
    final String ARseries = "Rules Used";
    final String HTseries = "Hints Used";
    //final String ETseries = "Elapsed Time";

    /* Prepare column Info */


    final DefaultCategoryDataset Alldataset = new DefaultCategoryDataset();

    for(i=0; i<puzzleIDs.length; i++){
        if(misconceptionPrecent[i] != "N/A"){
             Alldataset.addValue(Double.parseDouble(misconceptionPrecent[i]), MCseries, puzzleIDstr[i]);
        }else{
             Alldataset.addValue(0.0, MCseries, puzzleIDstr[i]);
        }

        if(TotalRulesPrecent[i] !="N/A"){
            Alldataset.addValue(Double.parseDouble(TotalRulesPrecent[i]), ARseries, puzzleIDstr[i]);
        }else{
            Alldataset.addValue(0.0, ARseries, puzzleIDstr[i]);
        }

        if(HintsUsedPrecent[i]!="N/A" ){
            Alldataset.addValue(Double.parseDouble(HintsUsedPrecent[i]), HTseries, puzzleIDstr[i]);
        }else{
            Alldataset.addValue(0.0, HTseries, puzzleIDstr[i]);
        }
    }

    /*for(i=0; i<puzzleIDs.length; i++){
        ETdataset.addValue(elapsedTime[i], ETseries, puzzleIDstr[i]);
    }*/

    JFreeChart allChart = ChartFactory.createLineChart(
        "Rules , misconception and hints relation Chart",       // chart title
        "Puzzle ID",                   // domain axis label
        "Precentage",     // range axis label
        Alldataset,                   // data
        PlotOrientation.VERTICAL,  // orientation
        true,                      // include legend
        true,                      // tooltips
        false                      // urls
    );
    allChart.setBackgroundPaint(Color.white);

    CategoryPlot allplot = allChart.getCategoryPlot();
    allplot.setBackgroundPaint(Color.white);
    allplot.setDomainGridlinePaint(Color.white);
    allplot.setRangeGridlinePaint(Color.white);

    final LineAndShapeRenderer allrenderer = (LineAndShapeRenderer) allplot.getRenderer();

    allrenderer.setShapesVisible(true);
    allrenderer.setSeriesPaint(0, Color.red);

    allrenderer.setSeriesPaint(0, Color.red);
    allrenderer.setSeriesPaint(1, Color.blue);
    allrenderer.setSeriesPaint(2, Color.green);

    allrenderer.setStroke(

    new BasicStroke(2f, BasicStroke.JOIN_ROUND, BasicStroke.JOIN_BEVEL)

    );

    String allChartfilename = ServletUtilities.saveChartAsPNG(allChart,  550, 450, null, session);
    String allChartURL = request.getContextPath() + "/DisplayChart?filename=" +allChartfilename;
    out.println();

%>


    <img src="<%= rulesChartURL %>" border=0 usemap="#<%= rulesChartfilename%>"><br/><br/>
    <img src="<%= hintsChartURL %>" border=0 usemap="#<%= hintsChartfilename%>"><br/><br/>
    <img src="<%= allChartURL %>" border=0 usemap="#<%= allChartfilename%>"><br/><br/>


<%
    }
%>